我們的目標是希望可以實作用網頁遊玩奇雞連連,因此我們會需要前端將遊戲資料發request到後端去處理遊戲的邏輯。可能是判斷這步棋合不合遊戲規則、遊戲結束了沒或是AI給出的下一步怎麼走。
這邊先來簡單的用Rocket做出可以 get
& post
的api。
依照現代網頁框架的模式,所以我們需要一個 controller
當作路由,一個 repository
來處理遊戲邏輯。
我們會用到的是Rust的 Module
系統,也就是類似其他語言常見的 namespace
功能,這樣可以確保函式的名稱不會有衝突的問題,並且更好的分類各個 Module
在做的事情。
在 src
底下建立的資料夾都可以當作一個 Module
, 只要裡面含有 mod.rs
去宣告這個 Module
底下有哪些檔案就可以了。
先在 $project/src
底下新增一個叫 api
的資料夾,裡面有 game_api.rs
& mod.rs
。
api/game_api.rs
:
use rocket::{serde::json::Json};
use crate::repository::game_repo;
#[get("/user")]
pub fn get_user() -> Json<game_repo::User> {
let user = game_repo::get_user_data();
Json(user)
}
api/mod.rs
:
pub mod game_api;
repository
也是依樣畫葫蘆。
repository/game_repo.rs
:
use rocket::{serde::Deserialize, serde::Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct User {
name: String,
age: i32,
}
pub fn get_user_data() -> User {
User {
name: String::from("John"),
age: 14
}
}
repository/mod.rs
:
pub mod game_repo;
接著在 main.rs
引入 mod
:
#[macro_use]
extern crate rocket;
mod api;
use api::game_api::{get_user};
#[launch]
fn rocket() -> _ {
rocket::build()
.mount("/", routes![get_user])
}
接下來執行 cargo run
& curl 127.0.0.1:8000/user
:
在與網頁前端傳遞資料最常用的就是 Json
格式,crate
中有個 serde
是最多人使用的工具,一開始Rocket並沒有支援轉Json的工具,直到某個版本將這個crate直接加到內建裡。
再來是post的部分,先是 repository/game_repo.rs
:
pub fn set_user_data(user_info: Json<User>) -> User {
User {
name: user_info.name.clone(),
age: user_info.age.clone()
}
}
api/game_api.rs
:
#[post("/user", data="<user_info>")]
pub fn set_user(user_info: Json<game_repo::User>) -> Json<game_repo::User> {
let user = game_repo::set_user_data(user_info);
Json(user)
}
main.rs
:
#[macro_use]
extern crate rocket;
mod api;
use api::game_api::{get_user, set_user};
mod repository;
#[launch]
fn rocket() -> _ {
rocket::build()
.mount("/", routes![get_user])
.mount("/", routes![set_user])
}
執行curl -X POST 127.0.0.1:8000/user -d '{"name": "kevin", "age": 20}'
:
最終資料夾結構長這樣: